package com.power.sifa.correction.executor.impl;

import cn.hutool.core.util.ObjectUtil;
import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
import com.plf.common.domain.YesNo;
import com.plf.common.file.service.IFileService;
import com.plf.common.utils.PdfConvertUtil;
import com.plf.common.utils.StringUtil;
import com.plf.common.utils.WordUtil;
import com.plf.core.base.model.Ha_attachment;
import com.plf.core.base.service.Ha_attachmentService;
import com.power.sifa.approve.model.Apl_main;
import com.power.sifa.approve.model.Aprv_process_materials;
import com.power.sifa.approve.model.enumeration.Tp_procmaterialEnum;
import com.power.sifa.approve.service.Apl_mainService;
import com.power.sifa.approve.service.Aprv_process_materialsService;
import com.power.sifa.correction.model.Apl_condeploy_person;
import com.power.sifa.correction.model.Crc_person;
import com.power.sifa.correction.service.Apl_condeploy_personService;
import com.power.sifa.correction.service.Crc_personService;
import com.power.sifa.net.service.ApplyService;
import com.power.sifa.util.executor.AbstractPostExecutor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

@Component
@Slf4j
public class CorrectionCondeploy extends AbstractPostExecutor {

    // 用户id
    private String userid;
    // 环节分类标识
    private String category;
    // 用户名
    private String username;
    // 单位id
    private String sectionid;
    // 单位名称
    private String sectionname;
    // 部门id
    private String deptid;
    // 部门名称
    private String deptname;
    // 处理意见
    private String remark;
    // 行政区划
    private String adid;
    // 环节名称
    private String taskname;

    @Resource
    private Crc_personService crc_personService;
    @Resource
    private Apl_condeploy_personService apl_condeploy_personService;
    @Resource
    private ApplyService applyService;
    @Resource
    private Apl_mainService apl_mainService;
    @Resource
    private Ha_attachmentService ha_attachmentService;
    @Resource
    private Aprv_process_materialsService aprv_process_materialsService;

    @Resource
    private IFileService fileService;

    @Override
    public void init(Map<String, Object> initdata) {
        this.userid = (String) initdata.get("userid");
        this.category = (String) initdata.get("category");
        this.username = (String) initdata.get("username");
        this.sectionid = (String) initdata.get("sectionid");
        this.sectionname = (String) initdata.get("sectionname");
        this.deptid = (String) initdata.get("deptid");
        this.deptname = (String) initdata.get("deptname");
        this.remark = (String) initdata.get("remark");
        this.adid = (String) initdata.get("adid");
        this.taskname = (String) initdata.get("taskname");
    }


    private void buildCorrectionImg (WordUtil wordUtil, Map<String, Object> formData ) {
        if (ObjectUtil.isNotNull(formData) && formData.containsKey("apl_condeploy_person_avatar")
                && StringUtils.isNotEmpty(formData.get("apl_condeploy_person_avatar").toString())) {
            final String avater = formData.get("apl_condeploy_person_avatar").toString();
            if (StringUtils.isNotEmpty(avater)) {
                Map<String, WordUtil.Img> imgMap = new HashMap<>();
                List<String> attachMentId = new ArrayList<>(10);
                attachMentId.add(avater);
                Map<String, Ha_attachment> ha_attachmentMap = ha_attachmentService.getHa_attachmentMapByIds(attachMentId);
                Ha_attachment attachment2 = ha_attachmentMap.get(avater);
                try {
                    InputStream photoInputStream = fileService.getStream(attachment2.getBucket(), attachment2.getPath());
                    String fileType = attachment2.getFilename().substring(attachment2.getFilename().lastIndexOf("."));
                    File tempFile = File.createTempFile(attachment2.getId(), fileType);

                    if (ObjectUtil.isNotNull(photoInputStream)) {
                        byte[] photoByte = IOUtils.toByteArray(photoInputStream);
                        FileOutputStream fos = null;
                        try {
                            fos = new FileOutputStream(tempFile);
                            fos.write(photoByte);
                        } catch (IOException e) {
                            log.error("图片流转换异常 {}", e.getMessage());
                        } finally {
                            fos.close();
                        }
                    }
                    FileInputStream fileInputStream = new FileInputStream(tempFile);
                    WordUtil.Img img = wordUtil.new Img(fileInputStream, 65, 86);
                    imgMap.put("avatar", img);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                wordUtil.replaceTableImg(imgMap);
            }
        }
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> execute() throws Exception {
        Apl_main mainObj = apl_mainService.getById(super.applyid);

        // 1. 修改人员头像和状态为已布控
        Apl_condeploy_person cPersonObj = this.apl_condeploy_personService.getById(super.applyid);
        if(StringUtil.isEmpty(cPersonObj.getConstartdate())) {
            throw new RuntimeException("布控开始时间不能为空");
        }
        if(StringUtil.isEmpty(cPersonObj.getConenddate())) {
            throw new RuntimeException("布控结束时间不能为空");
        }
        Crc_person personObj = this.crc_personService.getById(cPersonObj.getPerid());
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        if(!StringUtil.isEmpty(cPersonObj.getAvatar())) {
            personObj.setAvatar(cPersonObj.getAvatar());
        }
        personObj.setFocus(YesNo.YES);
        personObj.setConstartdate(format.parse(cPersonObj.getConstartdate()));
        personObj.setConenddate(format.parse(cPersonObj.getConenddate()));
        this.crc_personService.saveOrUpdate(personObj);

        // 2. 生成审批表
        Ha_attachment attachment;
        Map<String, Object> formData = this.applyService.formLoadField(mainObj.getFormid(), super.applyid);

        // 审批表意见和日期字段
        super.CorrectionField(formData);

        byte[] pdfByte;
        WordUtil wordUtil = new WordUtil("CorrectionCondeploy.docx");
        buildCorrectionImg(wordUtil, formData);
        wordUtil.replaceTable(formData);
        try (OutputStream os = wordUtil.createWord();
             InputStream is = new ByteArrayInputStream(((ByteArrayOutputStream) os).toByteArray())) {
            pdfByte = PdfConvertUtil.word2pdfWithFont(is);
            attachment = ha_attachmentService.upload(new ByteArrayInputStream(pdfByte), "社区矫正对象“雪亮工程”监督管理审批表.pdf");
            log.info("CorrectionCondeploy 社区矫正对象“雪亮工程”监督管理审批表 -> {}", attachment.getId());
        } catch (Exception e) {
            log.error("CorrectionCondeploy 案件受理审批表生成并保存失败 ->  msg[{}]", e.getMessage());
            throw new RuntimeException("CorrectionCondeploy 案件受理审批表生成并保存失败 -> " + e.getMessage());
        }

        // 3. 保存审批系统文书, 只存父流程
        Aprv_process_materials docObj = new Aprv_process_materials(Tp_procmaterialEnum.ADMRE_APPROVE);
        docObj.setId(super.applyid + NanoIdUtils.randomNanoId());
        // 通知书类型枚举
        docObj.setAttachid(attachment.getId());
        docObj.setCreateuserid(this.userid);
        docObj.setCreateuser(this.username);
        docObj.setCreatetime(new Date());
        docObj.setApplyid(super.applyid);
        this.aprv_process_materialsService.saveOrUpdate(docObj);
        return null;
    }
}
